package com.ht.pms.core.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ht.pms.core.common.cache.SalaryCodeBuilder;
import com.ht.pms.core.common.cache.SalaryServiceCache;
import com.ht.pms.core.common.constant.SalaryConstants;
import com.ht.pms.core.common.exception.ParamException;
import com.ht.pms.core.dao.SalaryBusinessDictDao;
import com.ht.pms.core.dao.SalaryTemplateDao;
import com.ht.pms.core.dao.SalaryTemplateDetailDao;
import com.ht.pms.core.dto.ReturnCodeEnum;
import com.ht.pms.core.dto.dict.DictParamsDto;
import com.ht.pms.core.dto.poi.ExcelBean;
import com.ht.pms.core.dto.tempalte.Template;
import com.ht.pms.core.dto.tempalte.TemplateDetail;
import com.ht.pms.core.dto.tempalte.TemplateDetailDto;
import com.ht.pms.core.dto.tempalte.TemplateDetailParam;
import com.ht.pms.core.dto.tempalte.TemplateDetailReq;
import com.ht.pms.core.dto.tempalte.TemplateDetailSortReq;
import com.ht.pms.core.dto.tempalte.TemplateReq;
import com.ht.pms.core.dto.tempalte.TemplateSelectType;
import com.ht.pms.core.handler.SalaryValidateDataHandler;
import com.ht.pms.core.service.SalaryTemplateService;
import com.ht.pms.core.util.PoiUtils;

@Service
public class SalaryTemplateServiceImpl implements SalaryTemplateService {
	private static final Logger LOGGER = LoggerFactory.getLogger(SalaryTemplateServiceImpl.class);

	// 薪资模板code生成
	private static final String SALARY_CODE_CACHE_KEY = "salary:code:template:";

	private static final String SALARY_TEMPLATE_TYPE_ISVIEW = "isView";
	private static final String SALARY_TEMPLATE_TYPE_ISMUST = "isMust";

	@Autowired
	private SalaryTemplateDao salaryTemplateDao;
	@Autowired
	private SalaryTemplateDetailDao salaryTemplateDetailDao;

	@Autowired
	private SalaryBusinessDictDao salaryBusinessDictDao;

	@Autowired
	private SalaryCodeBuilder salaryCodeBuilder;

	@Autowired
	private SalaryValidateDataHandler salaryValidateDataHandler;

	@Autowired
	private SalaryServiceCache salaryServiceCache;

	@Override
	public List<Template> getTemplateList(TemplateReq req) {
		return salaryTemplateDao.selectTemplateList(req);
	}
	
	@Override
	public List<Template> getTemplateListByType() {
		
		return salaryTemplateDao.selectTemplateListByType();
	}
	
	@Override
	public int getTemplateCount(TemplateReq req) {

		return salaryTemplateDao.selectTemplateCount(req);
	}
	
	

	@Override
	public SXSSFWorkbook downloadTemplate(String templateCode) throws Exception {
		List<ExcelBean> excelBeans = new ArrayList<>();
		// 创建表头信息， 对应dict_code字段
		List<DictParamsDto> fileList = salaryTemplateDetailDao.selectDictParamsByTemplateCode(templateCode);
		if (fileList != null) {
			for (DictParamsDto dictParamsDto : fileList) {
				excelBeans.add(new ExcelBean(dictParamsDto.getDictName(), dictParamsDto.getDictCode(), 0,
						dictParamsDto.getDictDataType()));
			}
			return PoiUtils.createExcelTemplate(excelBeans);
		}
		return null;
	}

	@Override
	public List<TemplateDetailDto> getTemplateDetailByTemplateCode(String templateCode) {
		// 可能是新增的模板，查询缓存
		List<TemplateDetailDto> details = salaryServiceCache.getTemplateDetails(templateCode);
		if (details != null && !details.isEmpty()) {
			return details;
		}
		return salaryTemplateDetailDao.selectByTemplateCode(templateCode);
	}

	@Override
	public Template getTemplateByTemplateCode(String templateCode) {

		return salaryTemplateDao.selectTemplateByTemplateCode(templateCode);
	}

	@Override
	public List<DictParamsDto> SalaryBusinessDictList() {

		return salaryBusinessDictDao.querySalaryBusinessDictTable();
	}

	@Transactional
	@Override
	public String saveTemplateDictParams(TemplateDetailReq req) {
		String templateCode = null;
		salaryValidateDataHandler.validateSalaryTemplateDetail(req);

		Set<String> set = new HashSet<>();
		List<String> fieldsList = new ArrayList<>();
		for (String field : req.getResultFields()) {
			if (set.add(field)) {
				fieldsList.add(field);
			}
		}

		List<TemplateDetail> insertParam = new ArrayList<>();
		List<TemplateDetail> updateParam = new ArrayList<>();
		if (StringUtils.isNotEmpty(req.getTemplateCode())) {
			List<TemplateDetailDto> templateDetaillist = salaryTemplateDetailDao
					.selectByTemplateCode(req.getTemplateCode());
			if (templateDetaillist == null) {
				LOGGER.error("[模板管理] 更新模板出错， 未找到编号[{}]", req.getTemplateCode());
				throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(),
						ReturnCodeEnum.ERROR_PARAM.getCodeDesc() + ": templateCode");
			}

			for (int i = 0; i < fieldsList.size(); i++) {
				boolean flag = false;
				for (TemplateDetailDto templateDetailDto : templateDetaillist) {
					if (fieldsList.get(i).equals(templateDetailDto.getDictCode())) {
						flag = true;

					}
				}

				// 新增
				TemplateDetail detail = new TemplateDetail();
				detail.setDictCode(fieldsList.get(i));
				detail.setIsMust(SalaryConstants.SALARY_NO);
				detail.setIsView(SalaryConstants.SALARY_YES);
				detail.setSort(i);
				detail.setTemplateCode(req.getTemplateCode());
				if (!flag) {
					insertParam.add(detail);
				} else {
					// 修改排序
					updateParam.add(detail);
				}
			}

			// 删除
			salaryTemplateDetailDao.deleteByDictCodeList(fieldsList, req.getTemplateCode());

			templateCode = req.getTemplateCode();
		} else {
			// 新增 。生成模板code 然后将字段列表缓存TemplateDetailDto
			templateCode = new StringBuilder().append("MB")
					.append(salaryCodeBuilder.generateDailyCode(SALARY_CODE_CACHE_KEY)).toString();

			List<DictParamsDto> dictParams = salaryBusinessDictDao.selectBatchDict(fieldsList);

			List<TemplateDetailDto> details = new ArrayList<TemplateDetailDto>();
			int index = 0;
			if (dictParams != null) {
				for (DictParamsDto dictParamsDto : dictParams) {
					index++;
					TemplateDetailDto detail = new TemplateDetailDto();
					detail.setDictCode(dictParamsDto.getDictCode());
					detail.setDictName(dictParamsDto.getDictName());
					detail.setIsView(SalaryConstants.SALARY_NO);
					detail.setIsMust(SalaryConstants.SALARY_NO);
					detail.setSort(index);
					details.add(detail);
				}
			}
			salaryServiceCache.cacheTemplateDetails(templateCode, details);
		}

		// 批量新增
		if (!insertParam.isEmpty()) {
			salaryTemplateDetailDao.insertBatchByTemplateCode(insertParam);
		}
		if (!updateParam.isEmpty()) {
			salaryTemplateDetailDao.updateSortBatchByTemplateCode(updateParam);
		}

		return templateCode;
	}

	@Override
	@Transactional
	public void saveTemplate(TemplateDetailParam req) {
		salaryValidateDataHandler.validateSalaryTemplate(req);

		Template template = salaryTemplateDao.selectTemplateByTemplateCode(req.getTemplateCode());

		if (template == null) {
			// 新增, 从缓存中获取
			salaryTemplateDao.insertTemplate(req);
			salaryTemplateDetailDao.insertBatchByTemplateCode(req.getTemplateDetails());
		} else {
			// 编辑
			salaryTemplateDao.UpdateTemplate(req);
			// 更新选择状态
			salaryTemplateDetailDao.updateBatchByTemplateCode(req.getTemplateDetails());
		}

		/*List<TemplateDetail> templateDetails = new ArrayList<>();
		if (templateDetailDtos != null) {
			for (TemplateDetailDto templateDetailDto : templateDetailDtos) {
				TemplateDetail detail = new TemplateDetail();
				detail.setIsMust(templateDetailDto.getIsMust());
				detail.setIsView(templateDetailDto.getIsView());

				if (req.getTemplateDetails() != null) {
					for (TemplateSelectType templateSelectType : req.getTemplateDetails()) {
						if (templateDetailDto.getDictCode().equals(templateSelectType.getDictCode())) {
							String name = templateSelectType.getName();
							Boolean value = templateSelectType.getValue();
							if (SALARY_TEMPLATE_TYPE_ISVIEW.equals(name) && value != null) {
								detail.setIsView(value ? SalaryConstants.SALARY_YES : SalaryConstants.SALARY_NO);
							}
							if (SALARY_TEMPLATE_TYPE_ISMUST.equals(name) && value != null) {
								detail.setIsMust(value ? SalaryConstants.SALARY_YES : SalaryConstants.SALARY_NO);
							}
						}
					}
				}
				detail.setTemplateCode(req.getTemplateCode());
				detail.setDictCode(templateDetailDto.getDictCode());
				detail.setSort(templateDetailDto.getSort());
				templateDetails.add(detail);
			}
		}*/
		salaryServiceCache.deleteTemplateDetails(req.getTemplateCode());
	}

	@Override
	public void sortTemplateDictParams(TemplateDetailSortReq req) {
		// 可能是新增的模板，查询缓存
		req.setTargetsort(req.getTargetsort() < 0 ? 0 : req.getTargetsort());
		
		List<TemplateDetailDto> details = salaryServiceCache.getTemplateDetails(req.getTemplateCode());
		List<TemplateDetail> templateDetails = new ArrayList<>();
		TemplateDetail  currDetail = new TemplateDetail();
		TemplateDetail  targetDetail = new TemplateDetail();
		
		if (details != null && !details.isEmpty()) {
			for (TemplateDetailDto templateDetailDto : details) {
				if(templateDetailDto.getTemplateDetailId() == req.getTemplateDetailId()) {
					copyTemplateDetailDto(templateDetailDto, currDetail);
					currDetail.setSort(req.getTargetsort());
				}
				if(templateDetailDto.getSort() == req.getTargetsort()) {
					copyTemplateDetailDto(templateDetailDto, targetDetail);
					targetDetail.setSort(req.getCurrentsort());
				}
			}
			 
			Iterator<TemplateDetailDto> iterator = details.iterator();
			while(iterator.hasNext()) {
				TemplateDetailDto detailDto = iterator.next();
				if(detailDto.getTemplateDetailId() == req.getTemplateDetailId()) {
					detailDto.setSort(req.getTargetsort());
					continue;
				}
				if(detailDto.getSort() == req.getTargetsort()) {
					detailDto.setSort(req.getCurrentsort());
				}
			}
			
			salaryServiceCache.cacheTemplateDetails(req.getTemplateCode(), details);
		}else {
			details = salaryTemplateDetailDao.selectByTemplateCode(req.getTemplateCode());
			for (TemplateDetailDto templateDetailDto : details) {
				if(templateDetailDto.getTemplateDetailId() == req.getTemplateDetailId()) {
					copyTemplateDetailDto(templateDetailDto, currDetail);
					currDetail.setSort(req.getTargetsort());
					continue;
				}
				if(templateDetailDto.getSort() == req.getTargetsort()) {
					copyTemplateDetailDto(templateDetailDto, targetDetail);
					targetDetail.setSort(req.getCurrentsort());
				}
			}
			if(currDetail.getTemplateCode() != null) {
				templateDetails.add(currDetail);
			}
			if(targetDetail.getTemplateCode() != null) {
				templateDetails.add(targetDetail);
			}
			salaryTemplateDetailDao.updateSortBatchByTemplateCode(templateDetails);
		}
		
	}

	private void copyTemplateDetailDto(TemplateDetailDto templateDetailDto, TemplateDetail currDetail) {
		currDetail.setTemplateCode(templateDetailDto.getTemplateCode());
		currDetail.setDictCode(templateDetailDto.getDictCode());
		currDetail.setSort(templateDetailDto.getSort());
	}


}
